//  Inside Microsoft Exchange 2007 Web Services 
//  Chapter 9
//
//  Copyright (c) 2007 David Sterling, Ben Spain, Mark Taylor, Huw Upshall, Michael Mainer.  
//  All rights reserved.
//
using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography.X509Certificates;
using System.Net;
using System.Net.Security;
using ProxyHelpers.EWS;

namespace GetIndexOfOccurrenceFromARecurringSeries
{
    class Program
    {
        static void Main(string[] args)
        {
            System.Net.ServicePointManager.ServerCertificateValidationCallback =
                delegate(Object obj, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
                {
                    return true;
                };

            ExchangeServiceBinding binding = new ExchangeServiceBinding();
            binding.Url = @"https://yourServer/ews/Exchange.asmx";
            binding.Credentials = new NetworkCredential(
                "username",
                "password",
                "domain");

            // You must first have the ItemId of a recurring master before you can call the 
            // GetIndexOfOccurrenceFromARecurringSeries below
        }

        /// <summary>
        /// Get the index of an occurrence by enumerating through a recurring series
        /// looking for a matching Start date (Listing 9-8)
        /// </summary>
        /// <param name="binding">Binding to use for the web service call</param>
        /// <param name="idOfRecurringMaster">id of the recurring master</param>
        /// <param name="startDate">Date Time value to search with</param>
        /// <returns>Index of the occurrence</returns>
        ///
        public static int GetIndexOfOccurrenceFromARecurringSeries(
            ExchangeServiceBinding binding,
            ItemIdType idOfRecurringMaster,
            DateTime startDate)
        {
            int currentIndex = 1;
            int idGroupSize = 15;

            // Create a group of OccurrenceItemIdType instances
            // and start enumerating until we find a matching
            // DateTime, or we receive an
            //  ErrorCalendarOccurrenceIndexIsOutOfRecurrenceRange
            // response code.
            //
            OccurrenceItemIdType[] occurrenceItemIds = new OccurrenceItemIdType[idGroupSize];

            PathToUnindexedFieldType startDateFieldURI =
                new PathToUnindexedFieldType();
            startDateFieldURI.FieldURI = UnindexedFieldURIType.calendarStart;

            GetItemType getItemRequest = new GetItemType();
            getItemRequest.ItemShape = new ItemResponseShapeType();
            getItemRequest.ItemShape.BaseShape = DefaultShapeNamesType.IdOnly;
            getItemRequest.ItemShape.AdditionalProperties =
                new PathToUnindexedFieldType[] { startDateFieldURI };

            while (true)
            {
                for (int x = 0; x < idGroupSize; x++)
                {
                    occurrenceItemIds[x] = new OccurrenceItemIdType();
                    occurrenceItemIds[x].RecurringMasterId = idOfRecurringMaster.Id;
                    occurrenceItemIds[x].ChangeKey = idOfRecurringMaster.ChangeKey;
                    occurrenceItemIds[x].InstanceIndex = currentIndex++;
                }
                getItemRequest.ItemIds = occurrenceItemIds;

                // Make the call to the GetItem web method, check each response message
                // for success.
                //
                GetItemResponseType response = binding.GetItem(getItemRequest);

                for (int y = 0; y < response.ResponseMessages.Items.Length; y++)
                {
                    ResponseMessageType responseMessage =
                        response.ResponseMessages.Items[y];
                    if (responseMessage.ResponseCode != ResponseCodeType.NoError)
                    {
                        throw new Exception(String.Format(
                            "GetItem request encountered a failure at InstanceIndex: " +
                            "{0}\r\n{1}\r\n{2}",
                                (currentIndex - idGroupSize) + y,
                                responseMessage.ResponseCode,
                                responseMessage.MessageText));
                    }

                    // Compare the Start value of the item at this index with the
                    // value we are looking for
                    CalendarItemType occurrenceItem =
                        (CalendarItemType)((ItemInfoResponseMessageType)responseMessage)
                            .Items.Items[0];

                    if (occurrenceItem.Start == startDate)
                    {
                        return (currentIndex - idGroupSize) + y;
                    }
                }
            }
        }
    }
}
